package com.apt.facade;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.apt.common.AptException;
import com.apt.common.DBUtility;
import com.apt.dao.DepartmentMasterDao;
import com.apt.dao.InstitutionMasterDao;
import com.apt.dao.LoadUsersDao;
import com.apt.dao.QuestionMasterDao;
import com.apt.dao.RoleMasterDao;
import com.apt.dao.StudentReportDao;
import com.apt.dao.TestMasterDao;
import com.apt.dao.TestTypeMasterDao;
import com.apt.dao.UserMasterDao;
import com.apt.dao.UserTestDao;
import com.apt.dao.UserTestEvalDao;
import com.apt.domain.StudentResult;
import com.apt.domain.UserTest;
import com.apt.domain.UserTestEval;
import com.apt.model.AptTest;
import com.apt.model.ForgotPwd;
import com.apt.model.LoginDetails;
import com.apt.model.Option;
import com.apt.model.Question;
import com.apt.model.StudentReport;

public class DataStoreHelper {

	public static List<Question> getQuestionsFromDataStore(String testId)
			throws AptException {

		return new QuestionMasterDao(DBUtility.getConnection())
				.getQuestionsForTest(Integer.parseInt(testId));

	}

	public static List<AptTest> getTestDetails() throws AptException {

		return new TestMasterDao(DBUtility.getConnection()).getAptTestDetails();

	}

	public static ForgotPwd getUserDetails(String collegeId)
			throws AptException {

		return new UserMasterDao(DBUtility.getConnection())
				.getUserDetails(collegeId);

	}

	public static int updatePwd(String userId, String pwd) throws AptException {
		return new UserMasterDao(DBUtility.getConnection()).updatePwd(userId,
				pwd);

	}

	public static LoginDetails validateUserAndPwd(String userId, String pwd)
			throws AptException {
		return new UserMasterDao(DBUtility.getConnection()).loginAndGetRoleId(
				userId, pwd);

	}

	public static String getRoleName(int roleId) throws AptException {

		return new RoleMasterDao(DBUtility.getConnection()).getRoleName(roleId);
	}

	public static Map<Integer, String> getTestTypes() throws AptException {

		return new TestTypeMasterDao(DBUtility.getConnection())
				.getTestTypes();

	}
	
	
	public static void updateTestResults(String userId, int testId,
			int totalQuestions, List<Question> quesAndAnsList)
			throws AptException {

		UserTestEvalDao eval = new UserTestEvalDao(DBUtility.getConnection());
		Integer lastAttemptNo = eval.getLastTestAttemptCount(userId, testId);
		if (lastAttemptNo == null) {
			lastAttemptNo = new Integer(1);

		} else {
			lastAttemptNo++;
		}
		int correct = 0;
		int incorrect = 0;
		//int unanswered = 0;
		List<UserTest> answers = new ArrayList<UserTest>();
		int iStudentChoice = 0;
		for (Question ques : quesAndAnsList) {
			List<Option> optList = ques.getOptions();
			String choice = null;
			String studentChoiceStr = ques.getStudentChoice();
			boolean isAnswered = false;
			if (studentChoiceStr == null) {
				isAnswered = false;

			} else {
				isAnswered = true;
				iStudentChoice = Integer.parseInt(ques.getStudentChoice());
			}

			int optId = 0;
			if (isAnswered) {
				for (Option opt : optList) {
					optId = Integer.parseInt(opt.getOptionId());

				
					if (optId == iStudentChoice) {
						
						if (opt.isCorrect()) {
							choice = "Y";
							correct++;
						} else {
							choice = "N";
							incorrect++;
						}

						break;
					} // End of if studentChoice
						

					
				} // End of Options Loop

			} //End of if answered
			else
			{
				// If not answered, the answer column will say N , since unasnwered also means wrong answer
				choice = "N";
				
			}
			

			UserTest utest = new UserTest(Integer.parseInt(ques
					.getQuestionId()), optId, choice);
			answers.add(utest);


		}// End of questions loop
		int attempted = correct + incorrect;
		int unAttempted = totalQuestions - attempted;

		//System.out.println("Correct ans:" + correct);
		//System.out.println("Incorrect and:" + incorrect);
		//System.out.println("Unattempted:" + unAttempted);

		double percentage = ((double) correct / (double) totalQuestions)
				* (double) 100;

		UserTestEval userTestEval = new UserTestEval(testId, userId, attempted,
				correct, incorrect, percentage, lastAttemptNo);
		Integer evalId = new UserTestEvalDao(DBUtility.getConnection())
				.insertAndGetTestEvalId(userTestEval);
		if (evalId == null) {

			throw new AptException(
					"Unable to get the user_test_evaluation_id for userId "
							+ userId + " and testId " + testId);
		}

		for (int count = 0; count < answers.size(); count++) {
			UserTest utest = (UserTest) answers.get(count);
			utest.setUserTestEvalId(evalId);
			answers.set(count, utest);

		}

		new UserTestDao(DBUtility.getConnection()).insertIntoUserTest(answers);

	}

	public static Map<Integer, String> getColleges() throws AptException {

		return new InstitutionMasterDao(DBUtility.getConnection())
				.getAllInstitutions();

	}
	
	public static Map<Integer, String> getDepartments() throws AptException {
		
		return new DepartmentMasterDao(DBUtility.getConnection()).getAllDepartments();


	}
	
	public static int getRoleId(String roleName)throws AptException{
		return new LoadUsersDao(DBUtility.getConnection()).getRoleId(roleName);
	}
	
	public static String[] getDepartmentName(int departmentId) throws AptException{
		return new LoadUsersDao(DBUtility.getConnection()).getDepartmentName(departmentId);
	}


	public static List<StudentReport> getStudentReport(int collegeId)
			throws AptException {

		Map<Integer, String> mapCollegeId = getColleges();
		List<AptTest> testmaster = getTestDetails();
		Map<Integer, Integer> map = getTestIdTotalQuestionsMap(testmaster);
		List<StudentReport> report = new ArrayList<StudentReport>();
		
		/*
		StudentReport sreport_first = new StudentReport("");
		sreport_first.setCollege("");
		sreport_first.setDepartment("");
		sreport_first.setName("");
		for(int k=0;k<testmaster.size();k++)
		{
			
			AptTest apttest = testmaster.get(k);
			
			setTestDesc(sreport_first, apttest.getTestName(), Integer.parseInt(apttest.getTestId()));
			
		}
		
		report.add(sreport_first);
		*/
		
		List<String> students = new StudentReportDao(DBUtility.getConnection()).getStudentsForCollege(collegeId);
		if (students.size() == 0) {
			throw new AptException(
					"No Students for this college in the database");

		}

		List<StudentResult> results = new StudentReportDao(DBUtility.getConnection()).getResults(collegeId);
		boolean isSet=false;
		for (String each : students) {
			StudentReport sreport = new StudentReport(each);
			isSet = false;
			for (StudentResult res : results) {
				if (each.equalsIgnoreCase(res.getUserId())) {
					isSet=true;
					String collegeName = mapCollegeId.get(collegeId);

					sreport.setCollege(collegeName);
					sreport.setDepartment(res.getDepartment());
					sreport.setName(res.getFirstName());
					int testId = res.getTestId();
					int totalQues = map.get(testId);
					setTestScore(testId,res.getCorrect(),totalQues,sreport);

				}

			} // End of studentResults
			
			if(isSet)
			{
				report.add(sreport);
				
			}

		} // End of Students

		
		return report;
	}
	
	public static int getTestDuration(int testId) throws AptException
	{
		return  new TestMasterDao(DBUtility.getConnection()).getTestDuration(testId);
		
	}
	
	public static void updateTestDetails(List<AptTest> update, Map<String,String> checkedMap) throws AptException
	{
		List<AptTest> outputList = new ArrayList<AptTest>();
		
		String testId;
		String checked;
		
		for(AptTest input:update)
		{
			testId=input.getTestId();
			checked=checkedMap.get(testId);
			if(checked != null && checked.equals("true"))
			{
				outputList.add(new AptTest(input.getTestId(),input.getTestName(),input.getTestDescription(),input.getTotalNumberOfQuesions(),input.getDisabled(),input.getDuration()));
				
				
			}
			
			
		}
		
		new TestMasterDao(DBUtility.getConnection()).updateTestDetails(outputList);
	}

	private static void setTestScore(int testId, int score, int totalQuestion,
			StudentReport sreport)

	{

		String scoreStr = score + "(" + totalQuestion + ")";
		switch (testId) {
		case 1:
			sreport.setTest1Score(scoreStr);
			break;

		case 2:
			sreport.setTest2Score(scoreStr);
			break;

		case 3:
			sreport.setTest3Score(scoreStr);
			break;

		case 4:
			sreport.setTest4Score(scoreStr);
			break;

		case 5:
			sreport.setTest5Score(scoreStr);
			break;
		case 6:
			sreport.setTest1Score(scoreStr);
			break;

		case 7:
			sreport.setTest2Score(scoreStr);
			break;

		case 8:
			sreport.setTest3Score(scoreStr);
			break;

		case 9:
			sreport.setTest4Score(scoreStr);
			break;

		case 10:
			sreport.setTest5Score(scoreStr);
			break;
		case 11:
			sreport.setTest4Score(scoreStr);
			break;

		case 12:
			sreport.setTest5Score(scoreStr);
			break;

		default:
			sreport.setTest1Score("Test Not Configured");
			break;

		}

	}
	
	private static void setTestDesc(StudentReport sreport,String name,int testId)

	{

		
		switch (testId) {
		case 1:
			sreport.setTest1Score(name);
			break;

		case 2:
			sreport.setTest2Score(name);
			break;

		case 3:
			sreport.setTest3Score(name);
			break;

		case 4:
			sreport.setTest4Score(name);
			break;

		case 5:
			sreport.setTest5Score(name);
			break;
		case 6:
			sreport.setTest1Score(name);
			break;

		case 7:
			sreport.setTest2Score(name);
			break;

		case 8:
			sreport.setTest3Score(name);
			break;

		case 9:
			sreport.setTest4Score(name);
			break;

		case 10:
			sreport.setTest5Score(name);
			break;
		case 11:
			sreport.setTest4Score(name);
			break;

		case 12:
			sreport.setTest5Score(name);
			break;

		default:
			sreport.setTest1Score(" Test Name Not Configured");
			break;

		}

	}

	private static Map<Integer, Integer> getTestIdTotalQuestionsMap(
			List<AptTest> testmaster) {
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();

		for (AptTest test : testmaster) {
			map.put(Integer.parseInt(test.getTestId()),
					test.getTotalNumberOfQuesions());

		}

		return map;

	}

	/*
	 * List<StudentReport> studentReportList = new ArrayList<StudentReport>();
	 * 
	 * StudentReport studentReport1 = new StudentReport("abc", 9, 10,
	 * "xyz college", "cse", 4); StudentReport studentReport2 = new
	 * StudentReport("def", 8, 11, "xyz college", "cse", 4); StudentReport
	 * studentReport3 = new StudentReport("ghi", 7, 12, "xyz college", "cse",
	 * 4); StudentReport studentReport4 = new StudentReport("jkl", 6, 13,
	 * "xyz college", "cse", 4); StudentReport studentReport5 = new
	 * StudentReport("mno", 5, 14, "xyz college", "cse", 4); StudentReport
	 * studentReport6 = new StudentReport("pqr", 4, 15, "xyz college", "cse",
	 * 4); StudentReport studentReport7 = new StudentReport("stu", 3, 16,
	 * "xyz college", "cse", 4); StudentReport studentReport8 = new
	 * StudentReport("vwx", 2, 17, "xyz college", "cse", 4); StudentReport
	 * studentReport9 = new StudentReport("yza", 1, 18, "xyz college", "cse",
	 * 4); StudentReport studentReport10 = new StudentReport("bcd", 10, 19,
	 * "xyz college", "cse", 4);
	 * 
	 * studentReportList.add(studentReport1);
	 * studentReportList.add(studentReport2);
	 * studentReportList.add(studentReport3);
	 * studentReportList.add(studentReport4);
	 * studentReportList.add(studentReport5);
	 * studentReportList.add(studentReport6);
	 * studentReportList.add(studentReport7);
	 * studentReportList.add(studentReport8);
	 * studentReportList.add(studentReport9);
	 * studentReportList.add(studentReport10);
	 * 
	 * 
	 * return studentReportList;
	 */

	/*
	 * 
	 * Option o1 = new Option("O1", "Kahlil Gibran"); Option o2 = new
	 * Option("O2", "Garcia Marquez"); Option o3 = new Option("O3",
	 * "Richard Bach"); List<Option> options = new ArrayList<Option>();
	 * options.add(o1); options.add(o2); options.add(o3); Question q1 = new
	 * Question("TEST1", "Q1",
	 * "Who's the author of the book titled One Hundred Years of Solitude?",
	 * options);
	 * 
	 * o1 = new Option("O1", "Murray"); o2 = new Option("O2", "DJokovic"); o3 =
	 * new Option("O3", "Federer"); options = new ArrayList<Option>();
	 * options.add(o1); options.add(o2); options.add(o3); Question q2 = new
	 * Question("TEST1", "Q2",
	 * "Who won Men's Singles Grand Slam for Wimbledon 2012 ?", options);
	 * 
	 * o1 = new Option("O1", "12"); o2 = new Option("O2", "11"); o3 = new
	 * Option("O3", "14"); options = new ArrayList<Option>(); options.add(o1);
	 * options.add(o2); options.add(o3); Question q3 = new Question("TEST1",
	 * "Q3", "How many lines does a sonnet have ?", options);
	 * 
	 * o1 = new Option("O1", "Tennis"); o2 = new Option("O2", "Soccer"); o3 =
	 * new Option("O3", "Baseball"); options = new ArrayList<Option>();
	 * options.add(o1); options.add(o2); options.add(o3); Question q4 = new
	 * Question("TEST1", "Q4",
	 * "To which sport is the term 'deuce' associated ?", options);
	 * 
	 * o1 = new Option("O1", "Beijing"); o2 = new Option("O2", "London"); o3 =
	 * new Option("O3", "Athens"); options = new ArrayList<Option>();
	 * options.add(o1); options.add(o2); options.add(o3); Question q5 = new
	 * Question("TEST1", "Q5", "Where is 2012 Olympics being held ?", options);
	 * questions.add(q1); questions.add(q2); questions.add(q3);
	 * questions.add(q4); questions.add(q5);
	 */

	/*
	 * List<AptTest> tests = new ArrayList<AptTest>();
	 * 
	 * AptTest tst1=new
	 * AptTest("T1","TEST1","Analytical Ability(45 min)","false"); AptTest
	 * tst2=new AptTest("T2","TEST2","Verbal Section(30 min)","false"); AptTest
	 * tst3=new AptTest("T3","TEST3","Technical Ability(40 min)","true");
	 * AptTest tst4=new
	 * AptTest("T4","TEST4","Logical Reasoning(50 min)","false"); AptTest
	 * tst5=new AptTest("T5","TEST5","Numerical Reasoning(45 min)","true");
	 * 
	 * tests.add(tst1); tests.add(tst2); tests.add(tst3); tests.add(tst4);
	 * tests.add(tst5);
	 */

}
